package org.dyndns.opendemogroup.gridgainoptimizer;

import java.io.Serializable;

import org.dyndns.opendemogroup.optimizer.GenericGenerationalGeneticAlgorithm;
import org.dyndns.opendemogroup.optimizer.OptimizationProfile;
import org.dyndns.opendemogroup.optimizer.RunResult;
import org.gridgain.grid.*;

/**
 * This class defines grid task for this example. Grid task is responsible for
 * splitting the task into jobs. This particular implementation splits given
 * string into individual words and creates grid jobs for each word.
 */
public class DistributedRunMapper<T> extends GridJobAdapter<String>
{

	/**
	 * Generated by Eclipse.
	 */
	private static final long serialVersionUID = -490238088812734801L;

	public DistributedRunMapper ( String profile )
	{
		super ( profile );
	}

	/**
	 * Invokes the {@link GenericGenerationalGeneticAlgorithm}, initialized
	 * with the supplied string representation of the OptimizationProfile.
	 */
	public Serializable execute ( ) throws GridException
	{
		// { Deserialize the profile from profileString
		String profileString = getArgument ( );

		/*
		 * Without the following, the local node complains with:
		 * [21:14:13,875][ERROR]
		 * [gridgain-#22%null%:comm-mgr-urgent-worker%GridGainOptimizer]
		 * [GridDeploymentCommunication] Failed to resolve resource:
		 * META-INF/services/javax.xml.parsers.SAXParserFactory ...while the
		 * remote node displays: [21:14:13,875][ERROR]
		 * [gridgain-#16%null%:grid-job-worker%null][GridDeploymentManager]
		 * Failed to get resource due to remote failure: null ...on the other
		 * hand, JAXP will find and load the default implementation and proceed
		 * anyway, so technically, it's no big deal, but this should be reported
		 * as a bug to GridGain.
		 */
		System.setProperty ( "javax.xml.parsers.SAXParserFactory",
			"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl" );

		OptimizationProfile profile =
			OptimizationProfile.fromXmlString ( profileString );
		GenericGenerationalGeneticAlgorithm ggga =
			new GenericGenerationalGeneticAlgorithm ( profile );
		// }

		RunResult[] results;
		// { Actually execute the GGGA with the specified profile
		System.out.println ( "Executing for " + profile.MaximumRuns + " runs: "
				+ profile.Description );
		results = ggga.execute ( );
		// }

		StringBuilder sb = new StringBuilder ( );
		// { serialize "results" into "sb"
		for ( int i = 0; i < results.length; i++ )
		{
			final RunResult runResult = results[i];
			// BestFitness + "\t" + BestMember.toString + "\n"
			sb.append ( runResult.BestFitness );
			sb.append ( '\t' );
			sb.append ( runResult.BestMember );
			sb.append ( '\n' );
		}
		// }

		String result = sb.toString ( );
		return result;
	}

}
